#include "usart.h"

static const int RX_BUF_SIZE = 1024;
uint8_t x[]={0x55,0xAF,0x45,0x66,0xaa};
uint8_t y[]={0xAA,0xFF,0x03};
uint8_t Z[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
uint8_t Rx_flag=1;
uint16_t send_seq = 0;
static upacker_inst hmi_packer;
static void uart_init(void)
{
    const uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    uart_driver_install(UART_NUM_1,RX_BUF_SIZE*2,0,0,NULL,0);
    uart_param_config(UART_NUM_1, &uart_config);
    uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
};

static int sendchar(const char* logName, const char* data)
{
    const int len = strlen(data);
    const int txBytes = uart_write_bytes(UART_NUM_1, data, len);
    ESP_LOGI(logName, "Wrote %d bytes", txBytes);
    return txBytes;
}

static int SendData(uint8_t *data,uint16_t data_len)
{
    uart_write_bytes(UART_NUM_1,data,data_len);
    return 1;
}

static void test_send(const uint8_t *buff, uint8_t len) {
    upacker_pack(&hmi_packer, send_seq, 0x05D1, 0, 0x03, buff, len);
    send_seq++;
}

static void tx_task(void *arg)
{
    static const char *TX_TASK_TAG = "TX_TASK";
    esp_log_level_set(TX_TASK_TAG, ESP_LOG_INFO);
    while (1) {
        // SendData(x,sizeof(x));
        test_send(y,sizeof(y));
        vTaskDelay(100);
    }
}

static void rx_task(void *arg)
{
    static const char *RX_TASK_TAG = "RX_TASK";
    esp_log_level_set(RX_TASK_TAG, ESP_LOG_NONE);
    uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE+1);
    while (1) {
        const int rxBytes = uart_read_bytes(UART_NUM_1, data, RX_BUF_SIZE, 1000 / portTICK_PERIOD_MS);
        upacker_unpack(&hmi_packer, (uint8_t *) data, rxBytes);
        if (rxBytes > 0) {
            data[rxBytes] = 0;
            ESP_LOGI(RX_TASK_TAG, "Read %d bytes: '%s'", rxBytes, data);
            ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, data, rxBytes, ESP_LOG_INFO);
        }
    }
    free(data);
}

static void usart_packer_cb(uint8_t type, uint16_t seq, uint16_t cmd, const uint8_t *data, int len)
{
    if(type==0x04)
    {
        // ESP_LOGI("usart_packer_cb","type:0x%02x,seq:0x%04x,cmd:0x%04x,len:%d",type,seq,cmd,len);
        
    }
}


static void tx_task_init(void)
{
    xTaskCreate(rx_task, "uart_rx_task", 2048, NULL, configMAX_PRIORITIES, NULL);
}

static void rx_task_init(void)
{
    xTaskCreate(tx_task, "uart_tx_task", 2048, NULL, configMAX_PRIORITIES-1, NULL);
}

void usart_init(void)
{ 
    uart_init();
    SendData(Z,sizeof(Z));
    upacker_init(&hmi_packer, usart_packer_cb,SendData);
    tx_task_init();
    rx_task_init();
}


